/*
 * Copyright (c) 2015-2016, 2018, 2020 The Linux Foundation. All rights reserved.
 *
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#ifndef _IPQ5332_CLK_H
#define _IPQ5332_CLK_H

#include <asm/arch-qca-common/uart.h>

/*
 * UART registers
 */
#define GCC_APCS_CLOCK_BRANCH_ENA_VOTE		0x180B004
#define GCC_BLSP1_UART1_BCR			0x1802028
#define GCC_BLSP1_UART2_BCR			0x1803028
#define GCC_BLSP1_UART3_BCR			0x1804028

#define GCC_BLSP1_UART_BCR(id)	((id < 1) ? \
				(GCC_BLSP1_UART1_BCR):\
				(GCC_BLSP1_UART1_BCR + (0x1000 * id)))

#define GCC_BLSP1_UART_APPS_CMD_RCGR(id)	(GCC_BLSP1_UART_BCR(id) + 0x04)
#define GCC_BLSP1_UART_APPS_CFG_RCGR(id)	(GCC_BLSP1_UART_BCR(id) + 0x08)
#define GCC_BLSP1_UART_APPS_M(id)		(GCC_BLSP1_UART_BCR(id) + 0x0c)
#define GCC_BLSP1_UART_APPS_N(id)		(GCC_BLSP1_UART_BCR(id) + 0x10)
#define GCC_BLSP1_UART_APPS_D(id)		(GCC_BLSP1_UART_BCR(id) + 0x14)
#define GCC_BLSP1_UART_APPS_CBCR(id)		(GCC_BLSP1_UART_BCR(id) + 0x18)

#define GCC_UART_CFG_RCGR_MODE_MASK		0x3000
#define GCC_UART_CFG_RCGR_SRCSEL_MASK		0x0700
#define GCC_UART_CFG_RCGR_SRCDIV_MASK		0x001F

#define GCC_UART_CFG_RCGR_MODE_SHIFT		12
#define GCC_UART_CFG_RCGR_SRCSEL_SHIFT		8
#define GCC_UART_CFG_RCGR_SRCDIV_SHIFT		0

#define BLSP1_AHB_CLK_ENABLE			0x16
#define UART_RCGR_SRC_SEL			0x1
#define UART_RCGR_SRC_DIV			0x0
#define UART_RCGR_MODE				0x2
#define UART_CMD_RCGR_UPDATE			0x1
#define UART_CMD_RCGR_ROOT_EN			0x2
#define UART_CBCR_CLK_ENABLE			0x1

#define NOT_2D(two_d)				(~two_d)
#define NOT_N_MINUS_M(n,m)			(~(n - m))
#define CLOCK_UPDATE_TIMEOUT_US			1000

#define CMD_UPDATE      			0x1
#define ROOT_EN         			0x2
#define CLK_ENABLE      			0x1

/*
 * Qpic SPI Nand clock
 */

#define GCC_QPIC_IO_MACRO_CMD_RCGR		0x1832004
#define GCC_QPIC_IO_MACRO_CFG_RCGR		0x1832008
#define GCC_QPIC_IO_MACRO_CBCR			0x183200C
#define GCC_QPIC_AHB_CBCR_ADDR			0x1832010
#define GCC_QPIC_CBCR_ADDR			0x1832014
#define GCC_QPIC_SREGR				0x1832018
#define GCC_QPIC_SLEEP_CBCR			0x183201C

#define IO_MACRO_CLK_320_MHZ			320000000
#define IO_MACRO_CLK_266_MHZ			266000000
#define IO_MACRO_CLK_228_MHZ			228000000
#define IO_MACRO_CLK_200_MHZ			200000000
#define IO_MACRO_CLK_100_MHZ			100000000
#define IO_MACRO_CLK_24MHZ			24000000

#define QPIC_IO_MACRO_CLK       		0
#define QPIC_CORE_CLK           		1
#define XO_CLK_SRC				2
#define GPLL0_CLK_SRC				3
#define FB_CLK_BIT				(1 << 4)
#define UPDATE_EN				0x1

/*
 * GCC-SDCC Registers
 */

#define GCC_SDCC1_BCR				0x1833000
#define GCC_SDCC1_APPS_CMD_RCGR			0x1833004
#define GCC_SDCC1_APPS_CFG_RCGR			0x1833008
#define GCC_SDCC1_APPS_M			0x183300C
#define GCC_SDCC1_APPS_N			0x1833010
#define GCC_SDCC1_APPS_D			0x1833014
#define GCC_SDCC1_APPS_CBCR			0x183302C
#define GCC_SDCC1_AHB_CBCR			0x1833034
#define GCC_SDCC1_APPS_CFG_RCGR_MODE_SEL	(2 << 12)
#define GCC_SDCC1_APPS_CFG_RCGR_SRC_SEL		(2 << 8)
#define GCC_SDCC1_APPS_CFG_RCGR_SRC_DIV		(0xB << 0)

/*
 * Ethernet Clocks
 */
#define GCC_QDSS_AT_CMD_RCGR			0x0182D004
#define GCC_QDSS_AT_CFG_RCGR			0x0182D008
#define QDSS_AT_SRC_SEL				1 << 8
#define QDSS_AT_DIV_SEL				9 << 0

#define GCC_PCNOC_BFDCD_CFG_RCGR		0x1831008
#define GCC_PCNOC_BFDCD_CMD_RCGR		0x1831004
#define PCCNOC_BFDCD_SRC_SEL			1 << 8
#define	PCCNOC_BFDCD_DIV_SEL			0xF << 0

#define GCC_SYSTEM_NOC_BFDCD_CFG_RCGR		0x182E008
#define GCC_SYSTEM_NOC_BFDCD_CMD_RCGR		0x182E004
#define SYSTEM_NOC_BFDCD_SRC_SEL		2 << 8
#define SYSTEM_NOC_BFDCD_DIV_SEL		8 << 0

#define NSS_CC_PPE_CMD_RCGR			0x39B003E8
#define NSS_CC_PPE_CFG_RCGR			0x39B003EC
#define NSS_CC_PPE_SRC_SEL			0x6 << 8
#define NSS_CC_PPE_DIV_SEL			1 << 0

#define GCC_IM_SLEEP_CBCR			0x1834020
#define NSS_CC_NSS_CSR_CBCR			0x39B005E8
#define NSS_CC_NSSNOC_NSS_CSR_CBCR		0x39B005EC
#define GCC_UNIPHY0_SYS_CBCR			0x181600C
#define GCC_UNIPHY1_SYS_CBCR			0x1816018
#define GCC_UNIPHY1_AHB_CBCR			0x181601C
#define GCC_UNIPHY0_AHB_CBCR			0x1816010
#define NSS_CC_NSSNOC_PPE_CBCR			0x39B00420
#define GCC_MDIO_SLAVE_AHB_CBCR			0x181200C
#define GCC_MDIO_MASTER_AHB_CBCR		0x1812004
#define GCC_NSSCC_CBCR				0x1817034
#define GCC_NSSNOC_NSSCC_CBCR			0x1817030

#define PLL_POWER_ON_AND_RESET			0x9B780
#define PLL_REFERENCE_CLOCK			0x9B784
#define FREQUENCY_MASK				0xfffffdf0
#define INTERNAL_48MHZ_CLOCK			0x7

#define NSS_CC_CFG_CMD_RCGR			0x39B005E0
#define NSS_CC_CFG_CFG_RCGR			0x39B005E4
#define NSS_CC_SRC_SEL				2 << 8
#define NSS_CC_DIV_SEL				0xF << 0

#define GCC_NSSNOC_ATB_CLK			0x01817014
#define GCC_NSSNOC_QOSGEN_REF_CLK		0x0181701C
#define GCC_NSSNOC_TIMEOUT_REF_CLK		0x01817020
#define GCC_NSSNOC_SNOC_CBCR			0x01817028
#define GCC_NSSCFG_CLK				0x0181702C
#define GCC_NSSNOC_SNOC_1_CBCR			0x0181707C
#define GCC_CMN_BLK_ADDR			0x0183A000
#define GCC_CMN_BLK_AHB_CBCR_OFFSET		0x4
#define GCC_CMN_BLK_SYS_CBCR_OFFSET		0x8

#define GCC_CBCR_CLK_ENABLE			0x1

#define NSS_CC_PPE_FREQUENCY_RCGR		0x39B003E8
#define NSS_CC_PPE_SWITCH_CFG_ADDR		0x39B003F8
#define NSS_CC_PPE_SWITCH_BTQ_ADDR		0x39B00400
#define NSS_CC_PPE_SWITCH_CBCR			0x39B00408
#define NSS_CC_PPE_SWITCH_CFG_CBCR		0x39B00410
#define NSS_CC_PPE_EDMA_CBCR			0x39B00414
#define NSS_CC_PPE_EDMA_CFG_CBCR		0x39B0041C
#define NSS_CC_NSSNOC_PPE_CBCR			0x39B00420
#define NSS_CC_NSSNOC_PPE_CFG_CBCR		0x39B00424
#define GCC_PORT_MAC_ADDR			0x39B00428
#define NSS_CC_PORT1_RX_CBCR			0x39B00480
#define NSS_CC_UNIPHY_PORT1_RX_CBCR		0x39B004B4

#define MDIO_50MHZ_CLK_BASE			0x7a00610

#define GCC_USB_BCR				0x182C000
#define GCC_USB0_MASTER_CMD_RCGR		0x182C004
#define GCC_USB0_MASTER_CFG_RCGR		0x182C008
#define GCC_USB0_MASTER_M			0x182C00C
#define GCC_USB0_MASTER_N			0x182C010
#define GCC_USB0_MASTER_D			0x182C014
#define GCC_USB0_AUX_CMD_RCGR			0x182C018
#define GCC_USB0_AUX_CFG_RCGR			0x182C01C
#define GCC_USB0_AUX_M				0x182C020
#define GCC_USB0_AUX_N				0x182C024
#define GCC_USB0_AUX_D				0x182C028
#define GCC_USB0_MOCK_UTMI_CMD_RCGR		0x182C02C
#define GCC_USB0_MOCK_UTMI_CFG_RCGR		0x182C030
#define GCC_USB0_MOCK_UTMI_M			0x182C034
#define GCC_USB0_MOCK_UTMI_N			0x182C038
#define GCC_USB0_MOCK_UTMI_D			0x182C03C
#define GCC_USB0_MOCK_UTMI_DIV_CDIVR		0x182C040
#define GCC_USB0_MASTER_CBCR			0x182C048
#define GCC_USB0_MASTER_SREGR			0x182C04C
#define GCC_USB0_AUX_CBCR			0x182C050
#define GCC_USB0_MOCK_UTMI_CBCR			0x182C054
#define GCC_USB0_SLEEP_CBCR			0x182C058
#define GCC_USB0_PHY_CFG_AHB_CBCR		0x182C05C
#define GCC_USB0_BOOT_CLOCK_CTL			0x182C060
#define GCC_USB0_PHY_BCR			0x182C06C
#define GCC_USB3PHY_0_PHY_BCR			0x182C070
#define GCC_USB0_PHY_PIPE_MISC			0x182C074
#define GCC_USB0_PIPE_CBCR			0x182C078
#define GCC_USB0_LFPS_CMD_RCGR			0x182C07C
#define GCC_USB0_LFPS_CFG_RCGR			0x182C080
#define GCC_USB0_LFPS_M				0x182C084
#define GCC_USB0_LFPS_N				0x182C088
#define GCC_USB0_LFPS_D				0x182C08C
#define GCC_USB0_LFPS_CBCR			0x182C090
#define GCC_USB0_EUD_AT_CBCR			0x1830004

#define GCC_USB0_BOOT_CLOCK_CTL			0x182C060
#define GCC_QUSB2_0_PHY_BCR			0x182C068

#define GCC_USB0_LFPS_CFG_SRC_SEL		(0x1 << 8)
#define GCC_USB0_LFPS_CFG_SRC_DIV		(0x1F << 0)
#define LFPS_M					0x1
#define LFPS_N					0xFE
#define LFPS_D					0xFD
#define GCC_USB0_LFPS_MODE			(0x2 << 12)

#define GCC_USB0_AUX_CFG_MODE_DUAL_EDGE 	(2 << 12)
#define GCC_USB0_AUX_CFG_SRC_SEL		(0 << 8)
#define GCC_USB0_AUX_CFG_SRC_DIV		(0x17 << 0)

#define AUX_M					0x0
#define AUX_N					0x0
#define AUX_D					0x0

#define GCC_USB0_MASTER_CFG_RCGR_SRC_SEL	(1 << 8)
#define GCC_USB0_MASTER_CFG_RCGR_SRC_DIV	(0x7 << 0)

#define GCC_USB_MOCK_UTMI_MN_MODE		(2 << 12)
#define GCC_USB_MOCK_UTMI_SRC_SEL		(1 << 8)
#define GCC_USB_MOCK_UTMI_SRC_DIV		(0x13 << 0)
#define MOCK_UTMI_M				0x1
#define MOCK_UTMI_N				0xFE
#define MOCK_UTMI_D				0xFD

#define PIPE_UTMI_CLK_SEL			0x1
#define PIPE3_PHYSTATUS_SW			(0x1 << 3)
#define PIPE_UTMI_CLK_DIS			(0x1 << 8)

/*
 * PCIE
 * PCIE0 ---> PCIE3X1_0
 * PCIE1 ---> PCIE3X2
 * PCIE2 ---> PCIE3X1_1
 */
#define GCC_CONFIG_PCIE0			0
#define GCC_CONFIG_PCIE1			1
#define GCC_CONFIG_PCIE2			2

#define GCC_SNOC_PCIE3_2LANE_S_CBCR		0x182E048
#define GCC_SNOC_PCIE3_1LANE_S_CBCR		0x182E04C
#define GCC_SNOC_PCIE3_1LANE_1_M_CBCR		0x182E050
#define GCC_SNOC_PCIE3_2LANE_M_CBCR		0x182E07C
#define GCC_SNOC_PCIE3_1LANE_M_CBCR		0x182E080
#define GCC_SNOC_PCIE3_1LANE_1_S_CBCR		0x182E0AC

#define GCC_PCIE3X2_BASE			0x1828000
#define GCC_PCIE3X1_0_BASE			0x1829000
#define GCC_PCIE3X1_1_BASE			0x182A000
#define GCC_PCIE_AUX_CMD_RCGR			0x1828004
#define GCC_PCIE_AUX_CFG_RCGR			0x1828008
#define GCC_PCIE_AUX_M				0x182800C
#define GCC_PCIE_AUX_N				0x1828010
#define GCC_PCIE_AUX_D				0x1828014

#define GCC_PCIE3X2_BCR				(GCC_PCIE3X2_BASE+0x000)
#define GCC_PCIE3X2_AXI_M_CMD_RCGR		(GCC_PCIE3X2_BASE+0x018)
#define GCC_PCIE3X2_AXI_M_CFG_RCGR		(GCC_PCIE3X2_BASE+0x01C)
#define GCC_PCIE3X2_AHB_CBCR			(GCC_PCIE3X2_BASE+0x030)
#define GCC_PCIE3X2_AXI_M_CBCR			(GCC_PCIE3X2_BASE+0x038)
#define GCC_PCIE3X2_AXI_M_SREGR			(GCC_PCIE3X2_BASE+0x03C)
#define GCC_PCIE3X2_AXI_S_CBCR			(GCC_PCIE3X2_BASE+0x040)
#define GCC_PCIE3X2_AXI_S_SREGR			(GCC_PCIE3X2_BASE+0x044)
#define GCC_PCIE3X2_AXI_S_BRIDGE_CBCR		(GCC_PCIE3X2_BASE+0x048)
#define GCC_PCIE3X2_PIPE_CBCR			(GCC_PCIE3X2_BASE+0x068)
#define GCC_PCIE3X2_AUX_CBCR			(GCC_PCIE3X2_BASE+0x070)
#define GCC_PCIE3X2_RCHG_CMD_RCGR		(GCC_PCIE3X2_BASE+0x078)
#define GCC_PCIE3X2_RCHG_CFG_RCGR		(GCC_PCIE3X2_BASE+0x07C)
#define GCC_PCIE3X2_PHY_AHB_CBCR		(GCC_PCIE3X2_BASE+0x080)
#define GCC_PCIE3X2_AXI_S_CMD_RCGR		(GCC_PCIE3X2_BASE+0x084)
#define GCC_PCIE3X2_AXI_S_CFG_RCGR		(GCC_PCIE3X2_BASE+0x088)

#define GCC_PCIE3X1_0_BCR			(GCC_PCIE3X1_0_BASE+0x000)
#define GCC_PCIE3X1_0_AXI_CMD_RCGR		(GCC_PCIE3X1_0_BASE+0x018)
#define GCC_PCIE3X1_0_AXI_CFG_RCGR		(GCC_PCIE3X1_0_BASE+0x01C)
#define GCC_PCIE3X1_0_AHB_CBCR			(GCC_PCIE3X1_0_BASE+0x030)
#define GCC_PCIE3X1_0_AXI_M_CBCR		(GCC_PCIE3X1_0_BASE+0x038)
#define GCC_PCIE3X1_0_AXI_M_SREGR		(GCC_PCIE3X1_0_BASE+0x03C)
#define GCC_PCIE3X1_0_AXI_S_CBCR		(GCC_PCIE3X1_0_BASE+0x040)
#define GCC_PCIE3X1_0_AXI_S_SREGR		(GCC_PCIE3X1_0_BASE+0x044)
#define GCC_PCIE3X1_0_AXI_S_BRIDGE_CBCR		(GCC_PCIE3X1_0_BASE+0x048)
#define GCC_PCIE3X1_0_PIPE_CBCR			(GCC_PCIE3X1_0_BASE+0x068)
#define GCC_PCIE3X1_0_AUX_CBCR			(GCC_PCIE3X1_0_BASE+0x070)
#define GCC_PCIE3X1_PHY_AHB_CBCR		(GCC_PCIE3X1_0_BASE+0x078)
#define GCC_PCIE3X1_0_RCHG_CMD_RCGR		(GCC_PCIE3X1_0_BASE+0x07C)
#define GCC_PCIE3X1_0_RCHG_CFG_RCGR		(GCC_PCIE3X1_0_BASE+0x080)

#define GCC_PCIE3X1_1_BCR			(GCC_PCIE3X1_1_BASE+0x000)
#define GCC_PCIE3X1_1_AXI_CMD_RCGR		(GCC_PCIE3X1_1_BASE+0x004)
#define GCC_PCIE3X1_1_AXI_CFG_RCGR		(GCC_PCIE3X1_1_BASE+0x008)
#define GCC_PCIE3X1_1_AHB_CBCR			(GCC_PCIE3X1_1_BASE+0x00C)
#define GCC_PCIE3X1_1_AXI_M_CBCR		(GCC_PCIE3X1_1_BASE+0x014)
#define GCC_PCIE3X1_1_AXI_M_SREGR		(GCC_PCIE3X1_1_BASE+0x018)
#define GCC_PCIE3X1_1_AXI_S_CBCR		(GCC_PCIE3X1_1_BASE+0x01C)
#define GCC_PCIE3X1_1_AXI_S_SREGR		(GCC_PCIE3X1_1_BASE+0x020)
#define GCC_PCIE3X1_1_AXI_S_BRIDGE_CBCR		(GCC_PCIE3X1_1_BASE+0x024)
#define GCC_PCIE3X1_1_PIPE_CBCR			(GCC_PCIE3X1_1_BASE+0x068)
#define GCC_PCIE3X1_1_AUX_CBCR			(GCC_PCIE3X1_1_BASE+0x070)
#define GCC_PCIE3X1_1_AUX_SREGR			(GCC_PCIE3X1_1_BASE+0x074)
#define GCC_PCIE3X1_1_RCHG_CMD_RCGR		(GCC_PCIE3X1_1_BASE+0x078)
#define GCC_PCIE3X1_1_RCHG_CFG_RCGR		(GCC_PCIE3X1_1_BASE+0x07C)

#define GCC_PCIE_AUX_CFG_RCGR_MN_MODE		(0 << 12)
#define GCC_PCIE_AUX_CFG_RCGR_SRC_SEL		(0 << 8) /* SRC = XO */
#define GCC_PCIE_AUX_CFG_RCGR_SRC_DIV		(0x17 << 0)

#define GCC_PCIE_AXI_CFG_RCGR_SRC_SEL		(0x9 << 0)
#define GCC_PCIE_AXI_CFG_RCGR_SRC_DIV		(2 << 8)

#define GCC_PCIE_AXI_M_CFG_RCGR_SRC_SEL		(0x8 << 0)
#define GCC_PCIE_AXI_M_CFG_RCGR_SRC_DIV		(2 << 8)

#define GCC_PCIE_AXI_S_CFG_RCGR_SRC_SEL		(2 << 8)
#define GCC_PCIE_AXI_S_CFG_RCGR_SRC_DIV		(9 << 0)

#define GCC_PCIE3X2_AXI_S_CFG_RCGR_SRC_SEL	(2 << 8)
#define GCC_PCIE3X2_AXI_S_CFG_RCGR_SRC_DIV	(9 << 0)

#define GCC_PCIE_RCHG_CFG_RCGR_SRC_SEL		(1 << 8)
#define GCC_PCIE_RCHG_CFG_RCGR_SRC_DIV		(0xF << 0)

#define CMD_UPDATE				0x1
#define ROOT_EN					0x2
#define PIPE_CLK_ENABLE				0x4FF1
#define CLK_DISABLE				0x0
#define NOC_HANDSHAKE_FSM_EN			(1 << 15)
#define GCC_PCIE_PHY_PIPE_MISC_SRC_SEL		(0x1 << 8)

#ifdef CONFIG_QCA_MMC
void emmc_clock_init(void);
void emmc_clock_reset(void);
#endif
#ifdef CONFIG_PCI_IPQ
void pcie_v2_clock_init(int pcie_id);
void pcie_v2_clock_deinit(int pcie_id);
#endif
int uart_clock_config(struct ipq_serial_platdata *plat);
#ifdef CONFIG_USB_XHCI_IPQ
void usb_clock_init(void);
void usb_clock_deinit(void);
#endif

enum uniphy_clk_type {
	NSS_PORT1_RX_CLK_E = 0,
	NSS_PORT1_TX_CLK_E,
	NSS_PORT2_RX_CLK_E,
	NSS_PORT2_TX_CLK_E,
	UNIPHY0_PORT1_RX_CLK_E,
	UNIPHY0_PORT1_TX_CLK_E,
	UNIPHY0_PORT2_RX_CLK_E,
	UNIPHY0_PORT2_TX_CLK_E,
	UNIPHYT_CLK_MAX,
};

void eth_clock_init(void);

#endif /*IPQ5332_CLK_H*/
